你要和平还是尊严?和平就是屈服,尊严就是死。

概述

Python的Queue队列,主要用于多生产者和消费者模式下的队列实现,特别适合多线程时的消息交换。通过使用队列,把生产者和消费者分解开来,作为其中的中间件,比如生产者产生一个数据,然后放到queue队列中,queue队列在把这个数据放到消费者线程中。使用单线程不必用队列,但是队列对于多线程来说是不可或缺的。
它实现了常见的锁语法,临时阻塞线程,防止竞争,这有赖于Python对线程的支持。

Queue三种模式

FIFO模式

FIFO模式就是管道模式,就像一根管道一样,数据一个一个的进去,然后一个一个的出来,你可以设置这个管道运行进入数据的个数,然后数据进满了之后,一个一个数据出来,出来后又进数据。

LIFO模式

LIFO模式是后进先出模式,也就是堆栈,元素只能在栈顶堆入。就是后进的数据先出去,先进的数据最后出去。递归函数就是用的堆栈。

优先级队列

优先级队列的每个数据都带有一个优先值,优先值越小的越早出去,优先值相同的先放入队列的先出去。

三种模式使用方法

FIFO模式

使用方法

q1=Queue.Queue(maxsize=0)

maxsize表示队列中最多有多少个数据,数据堆满了后,堵塞队列,然后数据一个一个的出去。如果设置0表示队列的元素不设上限,可以有无数个数据,但是需要当心内存溢出。

LIFO模式

使用方法

q2=Queue.LifoQueue(maxsize=0)

这里的maxsize和上面的意义一样,但是LifoQueue()是先进后出模式,也就是说先进去的最后出来,有点像倒序的意思。

优先级模式

使用方法

q3=Queue.PriorityQueue(maxsize=0)

优先级模式,这里的元素优先顺序是按照sorted(list(entries))[0]的接过来定义的,而元素的结构形式通常是(priority_number,data)这样的元祖。

放入数据与取出数据

q=Queue.Queue(maxsize=10)
# 首先确定使用的模式,内部最多存储10个元素
q.put(x,block=True,timeout=None)
# 这里放入一个数据x,字符串数字都可以,一般来说不要修改配置,使用默认的就可以,直接q.put(x)。block=True表示队列堵塞,直到队列有空的地方出来再把元素传进去,timeout=10表示10秒后如果没有新的元素传进去就报错。
q.get(x,block=True,timeout=None)
# 这里是把数据x取出来,一般使用默认配置就好,知己q.get(x)。如果设置block=True,timeout=10,就是说如果10秒没有接收到数据就直接报错,如果设置block=False的话,timeout参数会被忽略,此时就是只要队列有元素就直接弹出这个元素,没有元素就直接报错。

其他对象

当队列空的时候

print q.Empty()
# 如果队列是空的就返回TRUE

判断队列是否为空这种很常用,如果队列的数据如果不为空,那么就执行后面的消费者,取出数据给消费者对象。

while not q.Empty():
    # 如果队列中还有数据的话
    print abs(q.get(x))
    # 获取队列的元素,打印出元素的绝对值。这里只是一个演示,一般会把q.get(x)传入一个函数中。

获取队列元素个数

print q.qsize()

队列是否满了

print q.full()
# 如果满了返回TRUE

堵塞调用进程

q.join()

阻塞调用线程,直到队列中的所有任务被处理掉。
只要有数据被加入队列,未完成的任务数就会增加。当消费者线程调用task_done()(意味着有消费者取得任务并完成任务),未完成的任务数就会减少。当未完成的任务数降到0,join()解除阻塞。

队列任务完成

q.task_done()

意味着之前入队的一个任务已经完成。由队列的消费者线程调用。每一个get()调用得到一个任务,接下来的task_done()调用告诉队列该任务已经处理完毕。
如果当前一个join()正在阻塞,它将在队列中的所有任务都处理完时恢复执行(即每一个由put()调用入队的任务都有一个对应的task_done()调用)。

代码实例1,不设置maxsize

list1=[1,2,3,4,5,6,7,8,9]
q=Queue.Queue()   
#管道模式正序
for x in list1:
    q.put(x)
    # 把元素一个一个加载进管道中
while not q.empty():
# 当管道的元素不为空的时候
    print q.get(x)
    # 打印出元素
    print 'queue size:' + str(q.qsize())
    # 打印队列中还剩下多少元素

运行结果:

1
queue size:8
2
queue size:7
3
queue size:6
4
queue size:5
5
queue size:4
6
queue size:3
7
queue size:2
8
queue size:1
9
queue size:0

代码实例2,设置maxsize

前面说过maxsize表示队列中最多有多少个数据,数据堆满了后,堵塞队列,然后数据一个一个的出去。

list1=[1,2,3,4,5,6,7,8,9]
q=Queue.Queue(maxsize=5)   
#管道内最多存在5个
for x in list1:
    q.put(x)
    # 管道内载入5个元素了
    while not q.empty():
        print q.get(x)
        print 'queue size:' + str(q.qsize())
        # 执行完了这5个元素
        q.task_done()
        q.join()
        #task_done和join()可以不加上去,至于两种用法看看上面写的

运行结果一致